package com.cby.android.olive.utils

import android.annotation.SuppressLint
import android.content.Context
import android.content.pm.ApplicationInfo
import android.content.pm.PackageInfo
import android.content.pm.PackageManager
import android.graphics.Bitmap
import android.graphics.drawable.BitmapDrawable
import android.graphics.drawable.Drawable
import android.os.Build
import android.text.TextUtils
import android.util.Log
import java.io.BufferedReader
import java.io.IOException
import java.io.InputStreamReader

const val TYPE_SYSTEM = 0x001.toInt()
const val TYPE_NORMAL = 0x002.toInt()

data class AppInfoBean(
    var appName: String,
    var packageName: String,
    var appIcon: Drawable,
    var versionName: String,
    var versionCode: Long,
    var type: Int
)

object AppUtils {

    /**
     * 通过包名找应用
     *
     * @param context Context
     * @param pkgName String?
     * @return Boolean
     */
    @SuppressLint("WrongConstant")
    @JvmStatic
    fun hasPackage(context: Context, pkgName: String?): PackageInfo? {
        if (TextUtils.isEmpty(pkgName)) {
            return null
        }
        var packageInfo:PackageInfo? = null
        try {
            packageInfo = context.packageManager.getPackageInfo(pkgName!!, PackageManager.MATCH_ALL)
        } catch (e: PackageManager.NameNotFoundException) {
            // 抛出找不到的异常，说明该程序已经被卸载
        }
        return packageInfo
    }

    @JvmStatic
    fun runCommand() {
        Thread(runnable).start()
    }

    /**
     * 获取已安装的应用获取线程
     */
    private val runnable: Runnable by lazy {
        Runnable {
            try {
                //命令:adb shell pm list package -3
                //可以获取到手机上已安装的第3方应用列表，去掉-3这个参数可以获取到全部的应用列表
                val process = Runtime.getRuntime().exec("pm list package -3");
                val bis = BufferedReader(InputStreamReader(process.inputStream));
                var line:String? = null
                while (bis.readLine()?.let { line = it } != null) {
                    Log.i("AppUtils", "runCommand, line=$line")
                }
            } catch (e: IOException) {
                Log.i("AppUtils","runCommand,e=${e.printStackTrace()}")
            }
        }
    }

    @SuppressLint("QueryPermissionsNeeded")
    fun getAppList(context: Context) : MutableList<AppInfoBean> {
        val appList = mutableListOf<AppInfoBean>()
        val pm = context.packageManager
        val packages = pm.getInstalledPackages(0);
        for (index in 1 until packages.size) {
            val packageInfo = packages[index]
            val packageName = packageInfo.packageName
            val appName = getAppName(context, packageName)
            val appIcon = packageInfo.applicationInfo.loadIcon(pm)
            val versionCode = getAppVersionCode(context, packageName)
            val versionName = getVersionName(context, packageName)
            // 判断系统/非系统应用
            if ((packageInfo.applicationInfo.flags and ApplicationInfo.FLAG_SYSTEM) == 0)
            {
                // 非系统应用
                Log.i("AppUtils","非系统应用, packageInfo=" + packageInfo.packageName)

                appList.add(AppInfoBean(appName, packageName, appIcon,  versionName,versionCode, TYPE_NORMAL))
            } else {
                // 系统应用
                Log.i("AppUtils","系统应用, packageInfo=" + packageInfo.packageName)
                appList.add(AppInfoBean(appName, packageName, appIcon,  versionName,versionCode, TYPE_SYSTEM))
            }
        }
        return appList
    }

    @JvmStatic
    fun getAppName(context: Context, packageName: String): String {
        return try {
            val manager = context.packageManager
            val info = manager.getPackageInfo(packageName, 0)

            val name: String = info.applicationInfo.loadLabel(manager).toString()
            Log.i("AppUtils","name = $name")

            val applicationInfo = manager.getApplicationInfo(packageName, 0)
            val name2 = manager.getApplicationLabel(applicationInfo).toString()
            Log.i("AppUtils","name2 = $name2")

            name
        }catch (e: Exception) {
            ""
        }
    }



    /**
     * 获取当前应用的版本号（versionCode）
     *
     * @param context
     * @return
     */
    @JvmStatic
    fun getAppVersionCode(context: Context, packageName: String): Long {
        return try {
            val manager = context.packageManager
            val info = manager.getPackageInfo(packageName, 0)
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
                info.longVersionCode
            } else {
                info.versionCode.toLong()
            }
        } catch (var3: Exception) {
            -1
        } catch (e: NoSuchMethodError) {
            -1
        }
    }

    /**
     * 通过包名判断某个应用的版本号（VersionCode）
     *
     * @param context
     * @return
     */
    @JvmStatic
    fun getVersionName(context: Context, packageName: String): String {
        return try {
            val manager = context.packageManager
            val info: PackageInfo = manager.getPackageInfo(packageName, 0)
            info.versionName
        }catch (e: Exception) {
            ""
        }
    }

    /**
     * 获取图标 bitmap
     * @param context
     */
    @JvmStatic
    fun getBitmap(context: Context, packageName: String) : Bitmap?{
        var packageManager: PackageManager? = null
        var applicationInfo: ApplicationInfo? = null
        try {
            packageManager = context.applicationContext.packageManager
            applicationInfo = packageManager.getApplicationInfo(
                packageName, 0)
            //xxx根据自己的情况获取drawable
            val d = packageManager?.getApplicationIcon(applicationInfo)
            //val appIcon = packageInfo.applicationInfo.loadIcon(getPackageManager())
            val bd = d as BitmapDrawable
            val bm = bd.bitmap;
            return bm;
        } catch (e:PackageManager.NameNotFoundException) {
            applicationInfo = null
        }
        return null
    }

}